package com.jzo2o.foundations.service.impl;

import cn.hutool.core.lang.generator.ObjectGenerator;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.IRegionService;
import com.jzo2o.foundations.service.IServeItemService;
import com.jzo2o.foundations.service.IServeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.mysql.utils.PageHelperUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 服务表 服务实现类
 * </p>
 *
 * @author yi
 * @since 2025-01-16
 */
@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {

    @Autowired
    private IServeItemService serveItemService;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private ServeMapper baseMapper;

    /**
     * 分页查询服务列表
     * @param servePageQueryReqDTO
     * @return
     */
    @Override
    public PageResult<ServeResDTO> pageList(ServePageQueryReqDTO servePageQueryReqDTO) {
        return PageHelperUtils.selectPage(servePageQueryReqDTO, () ->
                baseMapper.queryServeList(servePageQueryReqDTO.getRegionId()));
    }

    /**
     * 批量添加服务
     * @param dtoList
     */
    @Override
    public void batchAdd(List<ServeUpsertReqDTO> dtoList) {
        for (ServeUpsertReqDTO dto : dtoList) {
            //1.判断服务项是否存在
            ServeItem serveItem = serveItemService.getById(dto.getServeItemId());
            if(ObjectUtils.isEmpty(serveItem)){
                throw new ForbiddenOperationException("服务项不存在不能添加");
            }

            //2.判断服务项是否已经启动
            if (serveItem.getActiveStatus() != FoundationStatusEnum.ENABLE.getStatus()){
                throw new ForbiddenOperationException("服务项未启用不能添加");
            }

            //3.判断服务项是否已添加过
            int count = count(Wrappers.<Serve>lambdaQuery().eq(Serve::getRegionId, dto.getRegionId())
                            .eq(Serve::getServeItemId, dto.getServeItemId())
                    );
            if(count>0) {
                throw new ForbiddenOperationException("服务项不能重复添加");
            }
            //4.查询区域信息
            String cityCode = regionService.getById(dto.getRegionId()).getCityCode();

            //5.复制服务项为服务信息
            Serve serve = BeanUtils.copyBean(dto, Serve.class);
            serve.setCityCode(cityCode);

            //6.新增区域服务信息
            boolean result = this.save(serve);
            if(!result) {
                throw new DBException("添加服务项失败");
            }
        }

    }

    /**
     * 修改服务价格
     * @param id
     * @param price
     */
    @Transactional
    @Override
    public void updatePrice(Long id, BigDecimal price) {
        //1.判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在");
        }
        //2.判断服务是否已启用
        if (serve.getSaleStatus() == FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("服务已上架不能修改价格");
        }
        //3.修改服务价格
        boolean update = update(Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id)
                .set(Serve::getPrice, price));
        if(!update){
            throw new DBException("修改服务价格失败");
        }

    }

    /**
     * 上架服务
     * @param id
     */
    @Override
    public void onSale(Long id) {
        //1.判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在，禁止上架");
        }
        //2、判断是否有区域
        if(ObjectUtils.isEmpty(serve.getRegionId())){
            throw new ForbiddenOperationException("服务未关联区域，禁止上架");
        }
        //3、判断当前服务状态是否是上架
        if(serve.getSaleStatus() == FoundationStatusEnum.ENABLE.getStatus()){
            throw new ForbiddenOperationException("服务已上架，禁止重复上架");
        }
        //4.判断服务项是否存在
        ServeItem serveItem = serveItemService.getById(serve.getServeItemId());
        if(ObjectUtils.isEmpty(serveItem)){
            throw new ForbiddenOperationException("服务项不存在，禁止上架");
        }
        //5.判断服务项是否已启用
        if(serveItem.getActiveStatus() != FoundationStatusEnum.ENABLE.getStatus()){
            throw new ForbiddenOperationException("服务项未启用，禁止上架");
        }
        //6.修改状态
        boolean update = update(Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getSaleStatus, 2));
        if(!update){
            throw new DBException("服务上架失败");
        }
    }

    /**
     * 删除服务
     * @param id
     */
    @Override
    public void delete(Long id) {
        //1、判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在，禁止删除");
        }

        //2、判断服务是否已上架
        if(serve.getSaleStatus() != FoundationStatusEnum.INIT.getStatus()){
            throw new ForbiddenOperationException("服务不是草稿，禁止删除");
        }

        //5、删除服务
        int i = baseMapper.deleteById(id);
        if(i<=0){
            throw new DBException("服务删除失败");
        }
    }

    /**
     * 下架服务
     * @param id
     */
    @Override
    public void offSale(Long id) {
        //1.判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在，禁止下架");
        }
        //2、判断是否有区域
        if(ObjectUtils.isEmpty(serve.getRegionId())){
            throw new ForbiddenOperationException("服务未关联区域，禁止下架");
        }
        //3、判断当前服务状态是否是下架
        if(serve.getSaleStatus() == FoundationStatusEnum.DISABLE.getStatus()){
            throw new ForbiddenOperationException("服务已下架，禁止重复下架");
        }

        //4.修改状态
        boolean update = update(Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getSaleStatus, 1));
        if(!update){
            throw new DBException("服务下架失败");
        }
    }

    /**
     * 设置服务为热门
     * @param id
     */
    @Override
    public void onHot(Long id) {
        //1.判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在，禁止设置热门");
        }
        //2、判断是否有区域
        if(ObjectUtils.isEmpty(serve.getRegionId())){
            throw new ForbiddenOperationException("服务未关联区域，禁止设置热门");
        }
        //3、判断当前服务状态是否是热门
        if(serve.getIsHot()==1){
            throw new ForbiddenOperationException("服务已设为热门，禁止重复设置热门");
        }
        //6.修改状态
        boolean update = update(Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getIsHot, 1));
        if(!update){
            throw new DBException("设置热门失败");
        }
    }

    /**
     * 取消热门
     * @param id
     */
    @Override
    public void offHot(Long id) {
        //1.判断服务是否存在
        Serve serve = getById(id);
        if(ObjectUtils.isEmpty(serve)){
            throw new ForbiddenOperationException("服务不存在，禁止取消热门");
        }
        //2、判断是否有区域
        if(ObjectUtils.isEmpty(serve.getRegionId())){
            throw new ForbiddenOperationException("服务未关联区域，禁止取消热门");
        }
        //3、判断当前服务状态是否是热门
        if(serve.getIsHot() == 0){
            throw new ForbiddenOperationException("服务不是热门，禁止取消");
        }

        //4.修改状态
        boolean update = update(Wrappers.<Serve>lambdaUpdate().eq(Serve::getId, id).set(Serve::getIsHot, 0));
        if(!update){
            throw new DBException("服务取消热门失败");
        }
    }

    /**
     * 根据区域id和状态查询服务数量
     * @param id
     * @param status
     * @return
     */
    @Override
    public int queryServeCountByRegionIdAndSaleStatus(Long id, int status) {
        return baseMapper.queryServeCountByRegionIdAndSaleStatus(id, status);
    }

    /**
     * 根据服务项id和状态查询服务数量
     * @param id
     * @param status
     * @return
     */
    @Override
    public int queryServeCountByServeItemIdAndSaleStatus(Long id, int status) {
        return baseMapper.queryServeCountByServeItemIdAndSaleStatus(id, status);
    }
}
